<?php
/**
 * Created by PhpStorm.
 * User: aron
 * Date: 2019/5/7
 * Time: 9:07 PM
 */

include_once "../../Util/DebugUtil/DebugUtil.php";

class Person {
    private $name;
    private $age;
    public $gender;
    private $height;//私有属性，通过重写的方法__set/__get进行设置和获取

    /**
     * Person constructor.
     * @param $name
     * @param $age
     */
    public function __construct($name, $age)
    {
        echo "Person __construct\r\n";
        $this->name = $name;
        $this->age = $age;
    }

    /**
     * 析构方法
     */
    public function __destruct()
    {
        echo "Person __destruct\r\n";
    }

    // ctrl + I 可以在弹出菜单中选择要重写的方法
    public function __get($name)
    {
        // 调用对象的是有属性获取方法会调用该方法，比如如下的调用
        // $person->height
        echo "Person __get 【 \$name = $name 】 \r\n";

        // 可以使用PHP中的变量函数特性给属性赋值
        // 获取身高
        if ($name == "height") {
            return $this->$name;
        }
    }

    public function __set($name, $value)
    {
        // 调用对象的是有属性设置方法会调用该方法，比如如下的调用，$name为属性名称，$value为属性的值
        // $person->height = 180;
        // 重写了该方法调用对象的私有属性不会报错，否则会包不能访问私有属性的错误
        echo "Person __set 【 \$name => $name \$value => $value 】 \r\n";

        // 可以使用PHP中的变量函数特性给属性赋值
        // 设置身高
        if ($name == "height") {
            $this->$name = $value;
        }

    }

    public function __isset($name)
    {
        echo "Person __isset 【 \$name = $name 】 \r\n";
        if ($name == "height") {
            return isset($this->$name);
        }
        return FALSE;
    }

    public function __unset($name)
    {
        echo "Person __unset 【 \$name = $name 】 \r\n";
        if ($name == "height") {
            unset($this->$name);
        }
    }



    // commond + N 在弹出菜单中可以选择让IDE生成getter/setter方法
    /**
     * @return mixed
     */
    public function getName()
    {
        return $this->name;
    }

    /**
     * @param mixed $name
     */
    public function setName($name)
    {
        $this->name = $name;
    }

    /**
     * @return mixed
     */
    public function getAge()
    {
        return $this->age;
    }

    /**
     * @param mixed $age
     */
    public function setAge($age)
    {
        $this->age = $age;
    }

}

// Demo
{
    $person = new Person("xiaomin", 12);
    $person->setName("hello");
    $person->gender = "male";
    // $person->height = 180 会调用__set方法，只有调用了没有重写了setter方法的私有属性才会调用__set方法
    $person->height = 180;

    // $person->height 会调用__get方法，只有调用了没有重写了getter方法的私有属性才会调用__get方法
    echo "\$person->height = " . ($person->height) . "  \$person->name = ". ($person->getName()) . "\r\n";

    // isset 判断私有属性会调用__isset方法，在__isset方法中没有处理name属性的判断
    $isSetName = isset($person->name);
    echo "\$isSetName = $isSetName \r\n";

    // isset 判断私有属性会调用__isset方法，在__isset方法中会处理height属性的判断
    $isSetHeight = isset($person->height);
    echo "\$isSetHeight = $isSetHeight \r\n";

    // unset 设置私有属性会调用__unset方法
    // unset方法中会处理height，height会被重置
    unset($person->height);
    // unset方法中没有处理name
    unset($person->name);
    echo "\$person->height = " . ($person->height) . "  \$person->name = ". ($person->getName()) . "\r\n";
}

echo "END\r\n";

